import {
  Button,
  DrawerInstance,
  DrawerPlugin,
  Form,
  FormItem,
  Input,
  InputNumber,
  TabPanel,
  Tabs
} from "tdesign-vue-next";
import {IndexCreate} from "@/components/es/domain/IndexCreate";
import {getDefaultIndexInstance, IndexInstance} from "@/domain/IndexInstance";
import MessageUtil from "@/utils/model/MessageUtil";
import indexApi from "@/components/es/api/IndexApi";
import {useIndexStore, useSeniorSearchStore} from "@/store";
import useLoadingStore from "@/store/LoadingStore";
import {FieldList} from "@/components/IndexMapping";
import { Mapping } from "@/components/es/domain/IndexBase";
import {MappingField} from "@/components/IndexMapping/types";

/**
 * 索引创建
 *
 * 名字限制
 * - 不能是大写。
 * - 不能包含 \，/，*，?，"，<，>，|，(空格)，,，#等字符。
 * - 7.0 之后的版本不能再包含 : （冒号）字符了。
 * - 不能以 -，_，+ 开头。名字不能是 . 或者 ..。
 * - 不能长于 255 字节。需要注意的是某些字符是需要多个字节来表示的。
 */
export function indexAdd(): void {
  const index: Ref<IndexInstance> = ref<IndexInstance>(getDefaultIndexInstance());
  const activeKey = ref("1");
  const indexMappingRef = ref<any>(null);
  const mapping = ref(new Array<MappingField>());

  // 名字是否正确
  const nameError = computed(() => {
    const value = index.value.name;
    if (value.trim() === '') {
      return '';
    }

    // 不能是大写
    if (/[A-Z]+/.test(value)) {
      return '不能是大写';
    }

    // 不能包含 \，/，*，?，"，<，>，|，(空格)，,，#等字符。
    if (/[\\\/*?"<>|\s#]+/.test(value)) {
      return '不能包含 \\，/，*，?，"，<，>，|，(空格)，,，#等字符';
    }

    // 不能以 -，_，+ 开头。名字不能是 . 或者 ..。
    if (/^[_\-+]+/.test(value)) {
      return '不能以 -，_，+ 开头。名字不能是 . 或者 ..';
    }

    // 不能长于 255 字节。需要注意的是某些字符是需要多个字节来表示的。
    if (value.length > 255) {
      return '不能长于 255 字节';
    }
    return '';
  })

  let modalReturn: DrawerInstance = DrawerPlugin({
    header: "新建索引",
    size: "850px",
    default: () => <>
      <Form data={index}>
        <FormItem label="名称" help={nameError.value} labelAlign={'top'}>
          <Input v-model={index.value.name} maxlength={255} clearable
                 status={!!nameError.value ? 'error' : 'default'}></Input>
        </FormItem>
      </Form>
      <Tabs v-model={activeKey.value}>
        {{
          default: () => <>
            <TabPanel label="设置" value="1">
              <Form data={index.value.settings} layout="vertical">
                <FormItem label="分片数" labelAlign={'top'}>
                  <InputNumber v-model={index.value.settings.number_of_shards} theme={'column'}
                               style={{width: '160px'}}/>
                </FormItem>
                <FormItem label="副本数" labelAlign={'top'}>
                  <InputNumber v-model={index.value.settings.number_of_replicas} theme={'column'}
                               style={{width: '160px'}}/>
                </FormItem>
              </Form>
            </TabPanel>
            <TabPanel label="映射设置" value="2">
              <FieldList fields={mapping.value} setFields={e => mapping.value = e}/>
            </TabPanel>
          </>,
        }}
      </Tabs>
    </>,
    footer: () => <>
      <Button theme={'primary'} onClick={() => addIndex(index, modalReturn, indexMappingRef)}>新增</Button>
      <Button theme="default" onClick={() => modalReturn.destroy?.()}>取消</Button>
      <Button variant="text" theme={'primary'} onClick={() => copyIndex(index, modalReturn, indexMappingRef)}>复制到剪切板</Button>
      <Button variant="text" theme={'primary'}
              onClick={() => jumpToSeniorSearch(index, modalReturn, indexMappingRef)}>跳转到高级查询</Button>
    </>,
  });
}

function jumpToSeniorSearch(index: Ref<IndexInstance>, modalReturn: DrawerInstance, indexMappingRef: Ref<any>) {
  // 构建数据
  // 高级查询数据填充
  useSeniorSearchStore().loadEvent({
    link: '/' + index.value.name,
    method: 'PUT',
    body: JSON.stringify(getIndexCreate(index, indexMappingRef), null, 4)
  });
  modalReturn.destroy?.();
}

function copyIndex(index: Ref<IndexInstance>, modalReturn: DrawerInstance, indexMappingRef: Ref<any>) {
  // 执行拷贝
  utools.copyText(JSON.stringify(getIndexCreate(index, indexMappingRef), null, 4));
  MessageUtil.success("已成功复制到剪切板");
  modalReturn.destroy?.();
}

function addIndex(index: Ref<IndexInstance>, modalReturn: DrawerInstance, indexMappingRef: Ref<any>) {
  useLoadingStore().start("正在新增索引")
  // 新增
  indexApi(index.value.name).create(getIndexCreate(index, indexMappingRef))
    .then(res => MessageUtil.success(res, useIndexStore().reset))
    .catch(e => MessageUtil.error('索引创建错误', e))
    .finally(useLoadingStore().close);
  modalReturn.destroy?.()
}


function getIndexCreate(index: Ref<IndexInstance>, indexMappingRef: Ref<any>): IndexCreate {
  return {
    settings: index.value.settings,
    mappings: (indexMappingRef.value?.getMapping?.() ?? {}) as Record<string, Mapping>
  };
}
